﻿#region

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
using log4net;

#endregion

namespace Jiubang.Wap.Filter{
    ///<summary>
    /// 对指定数据流中包含的url链接添加前缀。<br/>
    /// 如果链接中waped参数大于二，则添加前缀后将该值修改为二。
    ///</summary>
    public sealed class AddUrlPrefixFilter : AbstractFilter{
        private static readonly string appDomainappVirtualPath;
        private static readonly Regex urlRegex;
        private readonly IList<string> exceptions;
        private readonly ILog log;
        private readonly string urlPrefix;

        static AddUrlPrefixFilter(){
            urlRegex = new Regex(@"<a\b[^>]+?\bhref=([""'])(.+?)\1", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
            appDomainappVirtualPath = HttpRuntime.AppDomainAppVirtualPath;
        }

        ///<summary>
        ///  对指定数据流中包含的url链接添加前缀。
        ///</summary>
        ///<param name = "stream">指定数据流</param>
        ///<param name = "urlPrefix">需要添加的前缀</param>
        ///<param name = "exceptions">不需要过滤的链接</param>
        public AddUrlPrefixFilter(Stream stream, string urlPrefix, IList<string> exceptions) : base(stream){
            if (stream == null) throw new ArgumentNullException("stream");
            if (exceptions == null) throw new ArgumentNullException("exceptions");
            if (urlPrefix == null) throw new ArgumentNullException("urlPrefix");
            log = LogManager.GetLogger(GetType());
            this.urlPrefix = urlPrefix;
            this.exceptions = exceptions;
        }

        public override string TextFilter(string text){
            try{
                return urlRegex.Replace(text, Replace);
            } catch (Exception ex){
                log.Warn(ex);
            }
            return text;
        }

        private string Replace(Match m){
            var input = m.Groups[2].Value;
            if (input.IndexOf(".aspx") == -1) return m.Value;
            var url = input.Replace("&amp;", "&");
            url=Regex.Replace(url, @"([&?])waped=(\d*)(&$)", "$1waped=9$3", RegexOptions.IgnoreCase);
            if (url.IndexOf("ad.3g.cn", StringComparison.CurrentCultureIgnoreCase) != -1) {
                return m.Value;
            }
            if (url.IndexOf("paike.3g.cn",StringComparison.OrdinalIgnoreCase)!=-1) {
                return m.Value;
            }
            if (!url.StartsWith("http://")){
                var host = ConfigurationManager.AppSettings["Host"];
                if (string.IsNullOrEmpty(host)){
                    if (url.StartsWith("/")) url = appDomainappVirtualPath + url;
                    else url = appDomainappVirtualPath + "/" + url;
                } else{
                    if (host.EndsWith("/") && url.StartsWith("/")) url = host.Remove(host.Length - 1) + url;
                    else if (host.EndsWith("/") == url.StartsWith("/")) url = host + "/" + url;
                    else url = host + url;
                }
            }
            foreach (var exception in exceptions){
                if (url.IndexOf(exception) >= 0) return m.Value;
            }
            return m.Value.Replace(input, urlPrefix + HttpUtility.UrlEncode(url));
        }
    }
}